#include <iostream>
#include <map>
using namespace std;

typedef map<int,int> x_map;
typedef map<int,x_map> y_map;
typedef map<int,int> active_map;





// Input: An empty events list. event is top or bottom of a rectangle.
// The function creates an arranged events list by inserting every event in the right place.
// The function taked into acount the posibility that several rectangles can start at the 
// same line (but not at the same space).
void create_events_list(y_map &events_list) 
{
	int in1=0, in2=0, in3=0;

	while(true)
	{
		cin >> in1;	//event line
		if (in1 == 0) break;
		cin >> in2; // first point
		cin >> in3; // second point  (in3-in2=rectangle width)

		if (events_list.find(in1) == events_list.end())		//check if rectangle exist in the events list	
			events_list[in1] = x_map();  // not exist => creating a new line (line and map to current events).
		events_list[in1][in2] = in3;	 // exist => just adding the new event to the correct line.
	}
	return ;
}

// Input: Active list - the existing rectangles at current line.
// Input: Current key - points on the current rectangle (to be erased).
// Input: Current_line - represent ehere are we in the sweep line proccess.
// The function calculates the spaces between the two rectangles that surounding the erased one.
int erase_calculate_space(active_map &active_list, int current_key, int current_line)
{
	int space;
	active_map::iterator current_it, left_it, right_it;

	current_it = active_list.find(current_key);
	right_it = current_it;
	left_it  = current_it;
	if((current_it++ != active_list.begin()) && (current_it != active_list.end())) 
	{	// check whether the (going to be) erased rectangle is the left most or the right most, so we skip calculations.
		right_it++;		// the rectangle from the right.
		left_it--;		// the rectangle from the left.
		space = right_it->first - left_it->second;
	//	cout << current_line+1 << "\t" << left_it->second << "\t" << right_it->first << "\t" << space << endl;
		cout << left_it->second << " " << current_line+1 << " " << space << endl;
	}
	else
		space = NULL;
	return space;
}

// Input: Active list - the existing rectangles at current line.
// Input: Current key - points on the current rectangle (inserted).
// Input: Current_line - represent ehere are we in the sweep line proccess.
// The function calculates the spaces between the two rectangles that surounding the erased one.
int insert_calculate_spaces(active_map &active_list, int current_key, int current_line)
{
	int space;
	active_map::iterator current_it, left_it, right_it;

	current_it = active_list.find(current_key);
	right_it = current_it;
	left_it  = current_it;
	if(current_it != active_list.begin())
	{	// check whether the (going to be) erased rectangle is the left most or the right most, so we skip calculations.
				
		left_it--;		// the rectangle from the left.
		space = current_it->first - left_it->second;
	//	cout << current_line << "\t" << left_it->second << "\t" << current_it->first << "\t" << space << endl;
		cout << left_it->second << " " <<  current_line << " " << space << endl;
	}
	right_it++;			// the rectangle from the right.
	if(right_it != active_list.end())
	{
		space = right_it->first - current_it->second;
	//	cout << current_line << "\t" << current_it->second << "\t" << right_it->first << "\t" << space << endl;
		cout << current_it->second << " " <<  current_line << " " << space << endl;
	}
	return 0;
}


// Input: Full arranged events list.
// The function run through all the events (x events in every y event).
// Everytime a rectangle starts or ends (event), it updates an active list and calculates the relevant spaces.
void create_active_list(y_map &events_list)
{
	int current_key = NULL;
	int current_line = NULL;
	x_map x_events;
	active_map active_list;
	x_map::iterator x_it;
	y_map::iterator y_it;

	y_it = events_list.begin();								//first event
	while(y_it != events_list.end())						//run over all y-axis events
	{						
		x_events = y_it->second;							//get all events from the same time/y_axis
		x_it = x_events.begin();
		current_line = y_it->first;

		while(x_it != x_events.end())						//run over all x-axis events
		{									
			active_map::iterator current_x_int = active_list.find(x_it->first);
			if ( current_x_int == active_list.end())		//check if already exist. no => insert ; yes => erase.
			{
				active_list[x_it->first] = x_it->second;	//insert x-axis event (from the same y-axis)
				insert_calculate_spaces(active_list, x_it->first, current_line);
			} 
			else		// x-axis event already exist => bottom of rect => erase from active list.
			{				
				current_key = current_x_int->first;
				erase_calculate_space(active_list, current_key, current_line);
				active_list.erase(current_x_int);
			}
			x_it++;	//next x event
		}
		y_it++;		//next y event

		

	}
	events_list.clear();
	return ;
}

// The function read the rectangles from afile in format: x1 y1 x2 y2.
// Than it creates two files for x_events and y_events.
int read_rectangles()
{
	int x1, x2=0, y1=0, y2=0;
	FILE *rect_file, *x_file, *y_file;

	if((rect_file=fopen("rectangles.txt", "r"))==NULL)
		return -1;
	if((x_file=fopen("x_events.txt", "w"))==NULL)
		return -1;
	if((y_file=fopen("y_events.txt", "w"))==NULL)
		return -1;
	while(true)
	{
		if(fscanf(rect_file, "%d %d %d %d", &x1, &y1, &x2, &y2) < 4) //read one rectangle / line.
			break;
		fprintf(x_file, "%d %d %d\n", y1, x1, x2); // write start rectangle x_event.
		fprintf(x_file, "%d %d %d\n", y2, x1, x2); // write end rectangle x_event.
		fprintf(y_file, "%d %d %d\n", x1, y1, y2); // write start rectangle y_event.
		fprintf(y_file, "%d %d %d\n", x2, y1, y2); // write end rectangle y_event.
	}
	fprintf(x_file, "%d %d %d\n", 0, 0, 0);
	fprintf(y_file, "%d %d %d\n", 0, 0, 0);
	fclose(rect_file);
	fclose(x_file);
	fclose(y_file);
	return 0;
}


// The function makes the stdin/out read and write to files (instead to the screen).
int open_files(const char* events_file_path, const char* spaces_file_path)
{
	if(freopen (events_file_path,"r",stdin)==NULL)
		return -1;
	if(freopen (spaces_file_path,"w",stdout)==NULL)
		return -1;
	return 0;
}

void close_files()
{
	fclose (stdin);
	fclose (stdout);
}

int main ()
{
	y_map events_list;
	read_rectangles();
	// run all for vertical sweep-line
	open_files("x_events.txt", "x_spaces.txt");
	create_events_list(events_list);
	create_active_list(events_list);
	close_files();

	// run all for horisontal sweep-line
	open_files("y_events.txt", "y_spaces.txt");
	create_events_list(events_list);
	create_active_list(events_list);
	close_files();
	return 0;
}
